package com.kvn.dal.core.task;

import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.kvn.dal.core.exception.SchedulerException;
import com.kvn.dal.core.pojo.JobLog;

/**
 * Created by wzy on 2017/5/24.
 */
public abstract class ExecutableTaskDeligate implements ExecutableTask {
    private static final Logger logger = LoggerFactory.getLogger(ExecutableTaskDeligate.class);

	private ExecutableTask executableTask;
	private final JobLog curJobLog = new JobLog(); // 当前代理执行的job信息

	public ExecutableTaskDeligate(ExecutableTask executableTask) {
		this.executableTask = executableTask;
	}


	@Override
	public void execute(JobExecutionContext context) throws JobExecutionException {
		// before
		try {
			doBefore(context, curJobLog);
		} catch (Exception e) {
			if(e instanceof SchedulerException){
				logger.error("[jobCode={}, corn={}] doBefore执行异常，job终止...END.....ERROR===>{}", curJobLog.getCode(), curJobLog.getCron(), e.getMessage());
				return;
			}

			logger.error("[jobCode={}, corn={}] doBefore执行异常，job终止...END.....ERROR===>{}", curJobLog.getCode(), curJobLog.getCron(), e);
			throw e;
		}

		try {
            logger.info("[jobCode={}, corn={}]开始执行.....", curJobLog.getCode(), curJobLog.getCron());
            long start = System.currentTimeMillis();
			executableTask.execute(context); // 执行
			long end = System.currentTimeMillis();
			logger.info("[jobCode={}, corn={}]执行完成，执行耗时[{}ms]", curJobLog.getCode(), curJobLog.getCron(), end - start);
		} catch (Exception e) {
            logger.error("[jobCode={}, corn={}]执行异常.....ERROR===>{}", curJobLog.getCode(), curJobLog.getCron(), e);

			doThrow(e, curJobLog);

			// 异常抛出，流程中止
			throw e;
		}

		// after
		doAfter(context, curJobLog);
	}

	protected abstract void doAfter(JobExecutionContext context, final JobLog curJobLog);

	protected abstract void doThrow(Exception e, final JobLog curJobLog);

	protected abstract void doBefore(JobExecutionContext context, final JobLog curJobLog);

}
